module klang.klang.打印输出.Klang打印输出_;
import 全局;
import std.conv: ·to = to;
import std.functional: ·fd = toDelegate;
import ··Klang节点_ = klang.klang.语法节点.Klang节点_;
import ··类型_ = klang.编译.类型.类型_;
import ··节点_ = klang.编译.语法节点.节点_;
import klang.编译.类型.枚举值.枚举值_: TK, SK, 字符_;
import klang.编译.核心.核心_: 整数_;
import klang.编译.系统.系统_: sys;
import klang.编译.语法节点.节点_: 基础节点_ = 节点_, 基础源文件_ = 源文件_, 节点数组_, nodeIsSynthesized;
import klang.编译.输出节点.输出节点_: EmitFlags, getEmitFlags, getCommentRange;
import klang.编译.类型.类型_: 编译选项基类_, 基础符号_ = 符号_, TransformationResult, 打印机_, 打印选项_, 打印助手_, SourceMapGenerator, EmitHint, IEmitTextWriter, ListFormat, 新行种类_;
import klang.编译.输出注释.输出注释_: emitTrailingCommentsOfPosition, emitBodyWithDetachedComments;
import klang.编译.转换.转换_: noEmitSubstitution, noEmitNotification;
import klang.编译.工具.工具_: 获取节点文本从源文件文本;
import klang.klang.常量值.Klang常量值_: 获取KSK关键字En文本, 获取KSK关键字文本;
import klang.klang.类型.klang类型_: KSK, 节点标志_, 编译选项_, Klang打印选项_, Klang输出种类_;
import klang.klang.工具.klang工具_: getContainingNodeArray, isExpression, 获取节点标志;
import klang.编译.扫描工具.扫描工具_: createRange, rangeIsOnSingleLine, rangeStartPositionsAreOnSameLine, rangeEndIsOnSameLineAsRangeStart;
import klang.编译.输出工具.输出工具_: 打印机基础环境_, 打印选项, 基础环境, 设置打印选项, 设置基础环境, 输出源文件, writeTokenNode, writePunctuation, writeKeyword, writeOperator, writeTokenText, decreaseIndent, writeLinesAndIndent, writeParameter, increaseIndent, _printNode = printNode, _printList = printList, _printFile = printFile, _writeNode = writeNode, _writeList = writeList, _writeFile = writeFile, writeToken, writeSpace, writeLine, writeLiteral, writeStringLiteral, writeSymbol, writeLineOrSpace, onBeforeEmitNode, onAfterEmitNode, writeTrailingSemicolon, getLinesBetweenNodes, getLeadingLineTerminatorCount, getClosingLineTerminatorCount, getSeparatingLineTerminatorCount, pipelineEmit, beginPrint, endPrint, getWrite, setWrite, emit, emitList, emitNodeList, emitShebangIfNeeded, emitTokenWithComment, setSourceFile;
import klang.klang.语法节点.Klang节点_: 表达式_, 语句_, 节点_ = Klang节点_, 源文件_ = Klang源文件_, 标识符_, 字面量类表达式基类_, 正则表达式字面量_, 块_, 合成注释_, 限定名_, 类型形参_, 形参声明_, 属性声明_, 方法声明_, 构建声明_, 释放声明_, 签名声明_, 函数类声明_, 索引签名_, 运算符签名_, 运算符签名元素_, 变量声明列表_, 变量声明_, 类型引用_, 函数类型_, 字面量类型_, 指针类型_, 数组类型_, 动态数组类型_, 括号类型_, 词典类型_, 元组类型节点_, 区间类型节点_, 类型列表_, 联合类型_, 变长参数_, 类型限定类型_, 表达式包含类型实参_, 符号引用表达式_, 导入成员_, 导入从成员_, 导入声明_, 导入从声明_, 导入从版本成员_, 导入从成员块_, 导入版本成员_, 导入成员块_, 版本表达式语句_, 程序声明_, 测试单元语句_, 版本语句_, 指令语句_, 空语句_, 变量语句_, 表达式语句_, 如果语句_, 循环语句_, 循环属于_, 当循环语句_, 跳出语句_, 继续语句_, 抛出语句_, 断言语句_, 调试语句_, 标签语句_, 延迟语句_, 删除语句_, 返回语句_, 假如语句_, 若是块_, 若是子句_, 默认子句_, 同步语句_, 尝试语句_, 捕获子句_, 继承子句_, 属性赋值_, 简洁属性赋值_, 函数声明_, 接口声明_, 对象声明_, 结构声明_, 枚举声明_, 类型声明_, 别名声明_, 枚举成员_, 数组字面量表达式_, 动态类字面量表达式_, 词典键值表达式_, 结构字面量表达式_, 接口字面量表达式_, 属性访问表达式_, 元素访问表达式_, 截取表达式_, 调用表达式_, 新建表达式_, 函数表达式_, 箭头函数_, 类型断言表达式_, 类型查询表达式_, 类型转换表达式_, 非空表达式_, 展开表达式_, 条件表达式_, 模板表达式_, 前缀一元表达式_, 后缀一元表达式_, 二元表达式_, 是函数类的, 表达式列表表达式_, 外部修饰符声明_, 标识符修饰符_;
bool 输出英文关键字 = false;
class Klang打印_ : 打印机_ {
    this() { }
    override dstring printNode(EmitHint hint, 基础节点_ node, 基础源文件_ sourceFile) {
        return _printNode(hint, node, sourceFile);
    }
    override dstring printList(ListFormat format, 节点数组_!(基础节点_) list, 基础源文件_ sourceFile) {
        return _printList(format, list, sourceFile);
    }
    override dstring printFile(基础源文件_ sourceFile) {
        return _printFile(sourceFile);
    }
    override void writeNode(EmitHint hint, 基础节点_ node, 基础源文件_ sourceFile = ··null!(基础源文件_), IEmitTextWriter writer = ··null!(IEmitTextWriter)) {
        _writeNode(hint, node, sourceFile, writer);
    }
    override void writeList(ListFormat format, 节点数组_!(基础节点_) list = ··null!(节点数组_!(基础节点_)), 基础源文件_ sourceFile = ··null!(基础源文件_), IEmitTextWriter writer = ··null!(IEmitTextWriter)) {
        if ((list is null) || (list.原型 is ··null!(基础节点_[]))) {
            return;
        }
        _writeList(format, list, sourceFile, writer);
    }
    override void writeFile(基础源文件_ sourceFile, IEmitTextWriter writer, SourceMapGenerator sourceMapGenerator = ··null!(SourceMapGenerator)) {
        _writeFile(sourceFile, writer, sourceMapGenerator);
    }
}
打印机_ klang创建输出打印机(TransformationResult r) {
    Klang打印选项_ _打印选项 = new Klang打印选项_(Klang输出种类_.无_);
    _打印选项.removeComments = true;
    _打印选项.newLine = 新行种类_.CarriageReturnLineFeed;
    _打印选项.noEmitHelpers = true;
    _打印选项.sourceMap = true;
    _打印选项.inlineSourceMap = false;
    _打印选项.inlineSources = false;
    _打印选项.extendedDiagnostics = true;
    _打印选项.writeBundleFileInfo = false;
    打印助手_ 打印助手 = 打印助手_();
    打印助手.onEmitNode = r.emitNodeWithNotification;
    打印助手.isEmitNotificationEnabled = r.isEmitNotificationEnabled;
    打印助手.substituteNode = r.substituteNode;
    return .klang创建打印机(_打印选项, 打印助手);
}
打印机_ klang创建打印机(打印选项_ _打印选项, 打印助手_ _打印助手) {
    .输出英文关键字 = (cast(Klang打印选项_)(_打印选项)).输出英文关键字;
    设置打印选项(_打印选项);
    打印机基础环境_ _基础环境 = new 打印机基础环境_(/* 目标 */ TK.Ir, /* 单行注释头 */ "//"d, /* 多行注释头 */ "/*"d, /*_多行注释尾 */ "*/"d);
    设置基础环境(_打印助手, _基础环境, cast(void delegate(EmitHint, 基础节点_, void delegate(EmitHint, 基础节点_)))(·fd(&noEmitNotification)), cast(基础节点_ delegate(EmitHint, 基础节点_))(·fd(&noEmitSubstitution)), cast(dstring delegate(long))(·fd(&.获取关键字)), cast(bool delegate(基础节点_))(·fd(&.节点是否输出注释)), cast(bool delegate(基础节点_))(·fd(&.应停止注释输出)), cast(void delegate(EmitHint, 基础节点_))(·fd(&.pipelineEmitWithHintWorker)), cast(节点数组_!(基础节点_) delegate(基础节点_))(·fd(&getContainingNodeArray)));
    return new Klang打印_();
}
dstring 获取关键字(long token) {
    if (.输出英文关键字) {
        dstring 内容 = 获取KSK关键字En文本(token);
        if (内容 !is ··null!(dstring)) {
            return 内容;
        }
    }
    return 获取KSK关键字文本(token);
}
bool 节点是否输出注释(基础节点_ node) {
    return node.种类 != SK.源文件;
}
bool 应停止注释输出(基础节点_ node) {
    return node.目标种类 != KSK.变量声明列表;
}
void pipelineEmitWithHintWorker(EmitHint hint, 基础节点_ node) {
    if (node.种类 == SK.源文件) {
        return 输出源文件((cast(源文件_)((cast(基础源文件_)(node)))));
    }
    节点_ n = (cast(节点_)(node));
    if (hint == EmitHint.IdentifierName) {
        return .输出标识符((cast(标识符_)(n)));
    }
    if (hint == EmitHint.EmbeddedStatement) {
        return .输出空语句((cast(空语句_)(n)));
    }
    if ((n.标志 & 节点标志_.括号表达式) != 0 && (n.标志 & 节点标志_.忽略括号输出) == 0) {
        emitTokenWithComment(KSK.左括号, n.开始, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
        n.标志 |= (cast(整数_)(节点标志_.忽略括号输出));
        .输出表达式(n);
        n.标志 &= ~(cast(整数_)(节点标志_.忽略括号输出));
        emitTokenWithComment(KSK.右括号, n.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
        return;
    }
    if (hint == EmitHint.Unspecified) {
        switch (n.目标种类) {
            case KSK.合成注释: {
                return .输出合成注释((cast(合成注释_)(n)));
            }
            case KSK.模板头:
            case KSK.模板中:
            case KSK.模板尾: {
                return .输出字面量(n);
            }
            case KSK.标识符: {
                return .输出标识符((cast(标识符_)(n)));
            }
            case KSK.限定名: {
                return .输出限定名((cast(限定名_)(n)));
            }
            case KSK.运算符签名元素: {
                return .输出运算符签名元素((cast(运算符签名元素_)(n)));
            }
            case KSK.类型形参: {
                return .输出类型形参((cast(类型形参_)(n)));
            }
            case KSK.形参声明: {
                return .emitParameter((cast(形参声明_)(n)));
            }
            case KSK.属性声明: {
                return .输出属性声明((cast(属性声明_)(n)));
            }
            case KSK.方法声明: {
                return .输出方法声明((cast(方法声明_)(n)));
            }
            case KSK.释放声明: {
                return .输出释放声明((cast(释放声明_)(n)));
            }
            case KSK.构建声明: {
                return .输出构建声明((cast(构建声明_)(n)));
            }
            case KSK.索引签名: {
                return .输出索引签名((cast(索引签名_)(n)));
            }
            case KSK.运算符签名: {
                return .输出运算符签名((cast(运算符签名_)(n)));
            }
            case KSK.类型引用: {
                return .输出类型引用((cast(类型引用_)(n)));
            }
            case KSK.函数类型: {
                return .输出函数类型((cast(函数类型_)(n)));
            }
            case KSK.字面量类型: {
                return .输出字面量类型((cast(字面量类型_)(n)));
            }
            case KSK.指针类型: {
                return .输出指针类型((cast(指针类型_)(n)));
            }
            case KSK.数组类型: {
                return .输出数组类型((cast(数组类型_)(n)));
            }
            case KSK.动态数组类型: {
                return .输出动态数组类型((cast(动态数组类型_)(n)));
            }
            case KSK.括号类型: {
                return .输出括号类型((cast(括号类型_)(n)));
            }
            case KSK.词典类型: {
                return .输出词典类型((cast(词典类型_)(n)));
            }
            case KSK.元组类型节点: {
                return .输出元组类型节点((cast(元组类型节点_)(n)));
            }
            case KSK.区间类型节点: {
                return .输出区间类型节点((cast(区间类型节点_)(n)));
            }
            case KSK.类型列表: {
                return .输出类型列表((cast(类型列表_)(n)));
            }
            case KSK.联合类型: {
                return .输出联合类型((cast(联合类型_)(n)));
            }
            case KSK.变长参数: {
                return .输出变长参数((cast(变长参数_)(n)));
            }
            case KSK.类型限定类型: {
                return .输出类型限定类型((cast(类型限定类型_)(n)));
            }
            case KSK.表达式包含类型实参: {
                return .输出表达式包含类型实参((cast(表达式包含类型实参_)(n)));
            }
            case KSK.导入成员: {
                return .输出导入成员((cast(导入成员_)(n)));
            }
            case KSK.导入声明: {
                return .输出导入声明((cast(导入声明_)(n)));
            }
            case KSK.导入从成员: {
                return .输出导入从成员((cast(导入从成员_)(n)));
            }
            case KSK.导入版本成员: {
                return .输出导入版本成员((cast(导入版本成员_)(n)));
            }
            case KSK.导入成员块: {
                return .输出导入成员块((cast(导入成员块_)(n)));
            }
            case KSK.导入从声明: {
                return .输出导入从声明((cast(导入从声明_)(n)));
            }
            case KSK.导入从版本成员: {
                return .输出导入从版本成员((cast(导入从版本成员_)(n)));
            }
            case KSK.导入从成员块: {
                return .输出导入从成员块((cast(导入从成员块_)(n)));
            }
            case KSK.版本表达式语句: {
                return .输出版本表达式语句((cast(版本表达式语句_)(n)));
            }
            case KSK.程序声明: {
                return .输出程序声明((cast(程序声明_)(n)));
            }
            case KSK.测试单元语句: {
                return .输出测试单元语句((cast(测试单元语句_)(n)));
            }
            case KSK.版本语句: {
                return .输出版本语句((cast(版本语句_)(n)));
            }
            case KSK.块: {
                return .输出块((cast(块_)(n)));
            }
            case KSK.指令语句: {
                return .输出指令语句((cast(指令语句_)(n)));
            }
            case KSK.空语句: {
                return .输出空语句((cast(空语句_)(n)));
            }
            case KSK.变量语句: {
                return .输出变量语句((cast(变量语句_)(n)));
            }
            case KSK.变量声明列表: {
                return .输出变量声明列表((cast(变量声明列表_)(n)));
            }
            case KSK.变量声明: {
                return .输出变量声明((cast(变量声明_)(n)));
            }
            case KSK.表达式语句: {
                return .输出表达式语句((cast(表达式语句_)(n)));
            }
            case KSK.如果语句: {
                return .输出如果语句((cast(如果语句_)(n)));
            }
            case KSK.循环语句: {
                return .输出循环语句((cast(循环语句_)(n)));
            }
            case KSK.循环属于: {
                return .输出循环属于((cast(循环属于_)(n)));
            }
            case KSK.当循环语句: {
                return .输出当循环语句((cast(当循环语句_)(n)));
            }
            case KSK.继续语句: {
                return .输出继续语句((cast(继续语句_)(n)));
            }
            case KSK.跳出语句: {
                return .输出跳出语句((cast(跳出语句_)(n)));
            }
            case KSK.抛出语句: {
                return .输出抛出语句((cast(抛出语句_)(n)));
            }
            case KSK.断言语句: {
                return .输出断言语句((cast(断言语句_)(n)));
            }
            case KSK.同步语句: {
                return .输出同步语句((cast(同步语句_)(n)));
            }
            case KSK.调试语句: {
                return .输出调试语句((cast(调试语句_)(n)));
            }
            case KSK.标签语句: {
                return .输出标签语句((cast(标签语句_)(n)));
            }
            case KSK.延迟语句: {
                return .输出延迟语句((cast(延迟语句_)(n)));
            }
            case KSK.删除语句: {
                return .输出删除语句((cast(删除语句_)(n)));
            }
            case KSK.返回语句: {
                return .输出返回语句((cast(返回语句_)(n)));
            }
            case KSK.假如语句: {
                return .输出假如语句((cast(假如语句_)(n)));
            }
            case KSK.若是块: {
                return .输出若是块((cast(若是块_)(n)));
            }
            case KSK.若是子句: {
                return .输出若是子句((cast(若是子句_)(n)));
            }
            case KSK.默认子句: {
                return .输出默认子句((cast(默认子句_)(n)));
            }
            case KSK.尝试语句: {
                return .输出尝试语句((cast(尝试语句_)(n)));
            }
            case KSK.捕获子句: {
                return .输出捕获子句((cast(捕获子句_)(n)));
            }
            case KSK.继承子句: {
                return .输出继承子句((cast(继承子句_)(n)));
            }
            case KSK.属性赋值: {
                return .输出属性赋值((cast(属性赋值_)(n)));
            }
            case KSK.简洁属性赋值: {
                return .输出简洁属性赋值((cast(简洁属性赋值_)(n)));
            }
            case KSK.函数声明: {
                return .输出函数声明((cast(函数声明_)(n)));
            }
            case KSK.接口声明: {
                return .输出接口声明((cast(接口声明_)(n)));
            }
            case KSK.对象声明: {
                return .输出对象声明((cast(对象声明_)(n)));
            }
            case KSK.结构声明: {
                return .输出结构声明((cast(结构声明_)(n)));
            }
            case KSK.枚举声明: {
                return .输出枚举声明((cast(枚举声明_)(n)));
            }
            case KSK.类型声明: {
                return .输出类型声明((cast(类型声明_)(n)));
            }
            case KSK.别名声明: {
                return .输出别名声明((cast(别名声明_)(n)));
            }
            case KSK.枚举成员: {
                return .输出枚举成员((cast(枚举成员_)(n)));
            }
            case KSK.标识符修饰符: {
                return .输出标识符修饰符((cast(标识符修饰符_)(n)));
            }
            case KSK.外部修饰符声明: {
                return .输出外部修饰符声明((cast(外部修饰符声明_)(n)));
            }
            default:
                {
                    if (isExpression(n)) {
                        hint = EmitHint.Expression;
                    }
                }
        }
    }
    if (hint == EmitHint.Expression) {
        switch (n.目标种类) {
            case KSK.省略表达式: {
                return;
            }
            case KSK.数字字面量:
            case KSK.小数字面量:
            case KSK.文本字面量:
            case KSK.字符字面量:
            case KSK.正则表达式字面量:
            case KSK.无替换模板字面量: {
                return .输出字面量(n);
            }
            case KSK.标识符: {
                return .输出标识符((cast(标识符_)(n)));
            }
            case KSK.符号引用表达式: {
                return .输出符号引用表达式((cast(符号引用表达式_)(n)));
            }
            case KSK.数组字面量表达式: {
                return .输出数组字面量表达式((cast(数组字面量表达式_)(n)));
            }
            case KSK.动态类字面量表达式: {
                return .输出动态类字面量表达式((cast(动态类字面量表达式_)(n)));
            }
            case KSK.词典键值表达式: {
                return .输出词典键值表达式((cast(词典键值表达式_)(n)));
            }
            case KSK.结构字面量表达式: {
                return .输出结构字面量表达式((cast(结构字面量表达式_)(n)));
            }
            case KSK.接口字面量表达式: {
                return .输出接口字面量表达式((cast(接口字面量表达式_)(n)));
            }
            case KSK.属性访问表达式: {
                return .输出属性访问表达式((cast(属性访问表达式_)(n)));
            }
            case KSK.元素访问表达式: {
                return .输出元素访问表达式((cast(元素访问表达式_)(n)));
            }
            case KSK.截取表达式: {
                return .输出截取表达式((cast(截取表达式_)(n)));
            }
            case KSK.调用表达式: {
                return .输出调用表达式((cast(调用表达式_)(n)));
            }
            case KSK.新建表达式: {
                return .输出新建表达式((cast(新建表达式_)(n)));
            }
            case KSK.函数表达式: {
                return .输出函数表达式((cast(函数表达式_)(n)));
            }
            case KSK.箭头函数: {
                return .输出箭头函数((cast(箭头函数_)(n)));
            }
            case KSK.类型断言表达式: {
                return .输出类型断言表达式((cast(类型断言表达式_)(n)));
            }
            case KSK.类型查询表达式: {
                return .输出类型查询表达式((cast(类型查询表达式_)(n)));
            }
            case KSK.类型转换表达式: {
                return .输出类型转换表达式((cast(类型转换表达式_)(n)));
            }
            case KSK.非空表达式: {
                return .输出非空表达式((cast(非空表达式_)(n)));
            }
            case KSK.展开表达式: {
                return .输出展开表达式((cast(展开表达式_)(n)));
            }
            case KSK.条件表达式: {
                return .输出条件表达式((cast(条件表达式_)(n)));
            }
            case KSK.模板表达式: {
                return .输出模板表达式((cast(模板表达式_)(n)));
            }
            case KSK.前缀一元表达式: {
                return .输出前缀一元表达式((cast(前缀一元表达式_)(n)));
            }
            case KSK.后缀一元表达式: {
                return .输出后缀一元表达式((cast(后缀一元表达式_)(n)));
            }
            case KSK.二元表达式: {
                return .输出二元表达式((cast(二元表达式_)(n)));
            }
            case KSK.表达式列表表达式: {
                return .输出表达式列表表达式((cast(表达式列表表达式_)(n)));
            }
            default: break;
        }
    }
    if (n.目标种类 >= KSK.跳出_ && n.目标种类 <= KSK.类型_) {
        return writeTokenNode(n, cast(void delegate(dstring))(·fd(&writeKeyword)));
    }
    if (n.目标种类 >= KSK.左大括号 && n.目标种类 <= KSK.等号 || n.目标种类 >= KSK.冒等号 && n.目标种类 <= KSK.异或等号) {
        return writeTokenNode(n, cast(void delegate(dstring))(·fd(&writePunctuation)));
    }
    assert(false, "has not emit node"c);
}
/**
 * KSK.文本字面量
 * KSK.数字字面量
 * KSK.字符字面量
 * KSK.小数字面量
 * KSK.正则表达式字面量
 * KSK.无替换模板字面量
 * KSK.模板头
 * KSK.模板中
 * KSK.模板尾
 * // 字面量类表达式基类_
 */
void 输出字面量(节点_ n) {
    dstring 文本值 = .获取节点的字面量文本(n);
    if ((打印选项.sourceMap || 打印选项.inlineSourceMap) && (n.目标种类 == KSK.文本字面量 || n.目标种类 == KSK.字符字面量 || n.目标种类 == KSK.无替换模板字面量 || n.目标种类 == KSK.模板头 || n.目标种类 == KSK.模板中 || n.目标种类 == KSK.模板尾)) {
        writeLiteral(文本值);
    }
    else {
        writeStringLiteral(文本值);
    }
}
void 输出标识符(··Klang节点_.Klang标识符_ n) {
    dstring 文本值 = ""d;
    if (!.可以使用原始文本(n)) {
        文本值 = n.标识符.内容;
        if ((getEmitFlags(n) & EmitFlags.标识符输出为文本_) != 0) {
            文本值 = `"`d ~ 文本值 ~ `"`d;
        }
        if ((n.标志 & 节点标志_.文本内容标识符) != 0) {
            文本值 = `$"`d ~ 文本值 ~ `"`d;
        }
    }
    else {
        文本值 = 获取节点文本从源文件文本(基础环境.currentSourceFile.内容, n, false);
    }
    if (n.符号 !is ··null!(基础符号_)) {
        writeSymbol(文本值, n.符号);
    }
    else {
        writeLiteral(文本值);
    }
}
void 输出合成注释(合成注释_ n) {
    return;
}
void 输出符号引用表达式(符号引用表达式_ n) {
    .emitModifiers(n, ·to!(节点数组_!(节点_))(n.修饰符));
    emit(n.表达式);
}
dstring 获取节点的字面量文本(节点_ n) {
    if ((n.目标种类 == KSK.文本字面量 || n.目标种类 == KSK.数字字面量 || n.目标种类 == KSK.字符字面量 || n.目标种类 == KSK.小数字面量 || n.目标种类 == KSK.正则表达式字面量 || n.目标种类 == KSK.无替换模板字面量 || n.目标种类 == KSK.模板头 || n.目标种类 == KSK.模板中 || n.目标种类 == KSK.模板尾) && ((cast(字面量类表达式基类_)(n)).文本原节点 !is ··null!(节点_))) {
        节点_ 文本原节点 = (cast(字面量类表达式基类_)(n)).文本原节点;
        if (文本原节点.目标种类 == KSK.标识符 || 文本原节点.目标种类 == KSK.数字字面量 || 文本原节点.目标种类 == KSK.小数字面量) {
            dstring 内容 = ""d;
            if (文本原节点.目标种类 == KSK.标识符 && .可以使用原始文本(文本原节点)) {
                内容 = 获取节点文本从源文件文本(基础环境.currentSourceFile.内容, (cast(基础节点_)(文本原节点)), false);
            }
            else if (文本原节点.目标种类 == KSK.数字字面量 || 文本原节点.目标种类 == KSK.小数字面量) {
                内容 = (cast(字面量类表达式基类_)(文本原节点)).内容;
            }
            return `"`d ~ 内容 ~ `"`d;
        }
        else {
            return .获取节点的字面量文本(文本原节点);
        }
    }
    else {
        return .获取字面量文本(n);
    }
}
dstring 获取字面量文本(节点_ n) {
    if (.可以使用原始文本(n)) {
        return 获取节点文本从源文件文本(基础环境.currentSourceFile.内容, (cast(基础节点_)(n)), false);
    }
    else {
        switch (n.目标种类) {
            case KSK.文本字面量: {
                return `"`d ~ (cast(字面量类表达式基类_)(n)).内容 ~ `"`d ~ .获取字面量节点后缀(n);
            }
            case KSK.字符字面量: {
                return "'"d ~ (cast(字面量类表达式基类_)(n)).内容 ~ "'"d ~ .获取字面量节点后缀(n);
            }
            case KSK.无替换模板字面量: {
                return "`"d ~ (cast(字面量类表达式基类_)(n)).内容 ~ "`"d ~ .获取字面量节点后缀(n);
            }
            case KSK.数字字面量:
            case KSK.小数字面量: {
                return (cast(字面量类表达式基类_)(n)).内容 ~ .获取字面量节点后缀(n);
            }
            case KSK.模板头: {
                return "`"d ~ (cast(字面量类表达式基类_)(n)).内容 ~ "${"d ~ .获取字面量节点后缀(n);
            }
            case KSK.模板中: {
                return "}"d ~ (cast(字面量类表达式基类_)(n)).内容 ~ "${"d ~ .获取字面量节点后缀(n);
            }
            case KSK.模板尾: {
                return "}"d ~ (cast(字面量类表达式基类_)(n)).内容 ~ "`"d ~ .获取字面量节点后缀(n);
            }
            case KSK.正则表达式字面量: {
                return `/`d ~ (cast(字面量类表达式基类_)(n)).内容 ~ `/`d ~ .获取字面量节点后缀(n);
            }
            case KSK.标识符: {
                return (cast(标识符_)(n)).标识符.内容;
            }
            default: break;
        }
    }
    assert(false, "不可及"c);
    return `""`d;
}
dstring 获取字面量节点后缀(节点_ n) {
    dstring 后缀 = ""d;
    ulong 标志 = n.标志;
    if (n.目标种类 == KSK.正则表达式字面量) {
        正则表达式字面量_ nn = (cast(正则表达式字面量_)(n));
        if (nn.匹配模式 == 字符_.g) {
            后缀 ~= "g"d;
        }
        if (nn.匹配模式 == 字符_.m) {
            后缀 ~= "m"d;
        }
        if (nn.匹配模式 == 字符_.i) {
            后缀 ~= "i"d;
        }
        if (nn.匹配模式 == 字符_.s) {
            后缀 ~= "s"d;
        }
        if (nn.匹配模式 == 字符_.x) {
            后缀 ~= "x"d;
        }
        标志 = (cast(整数_)(nn.匹配字符标志));
    }
    if ((标志 & 节点标志_.C) != 0) {
        后缀 ~= "c"d;
    }
    else if ((标志 & 节点标志_.W) != 0) {
        后缀 ~= "w"d;
    }
    else if ((标志 & 节点标志_.D) != 0) {
        后缀 ~= "d"d;
    }
    if ((标志 & 节点标志_.UL) != 0) {
        后缀 ~= "UL"d;
    }
    else if ((标志 & 节点标志_.L) != 0) {
        后缀 ~= "L"d;
    }
    else if ((标志 & 节点标志_.U) != 0) {
        后缀 ~= "U"d;
    }
    if ((标志 & 节点标志_.F) != 0) {
        后缀 ~= "f"d;
    }
    else if ((标志 & 节点标志_.I) != 0) {
        后缀 ~= "i"d;
    }
    else if ((标志 & 节点标志_.FI) != 0) {
        后缀 ~= "fi"d;
    }
    return 后缀;
}
bool 可以使用原始文本(节点_ n) {
    if (nodeIsSynthesized(n) || (n.标志 & 节点标志_.文本内容标识符) != 0 || (n.父节点 is ··null!(基础节点_)) || (基础环境 is ··null!(打印机基础环境_)) || (基础环境.currentSourceFile is ··null!(基础源文件_)) || (基础环境.currentSourceFile.内容 is ··null!(dstring))) {
        return false;
    }
    字面量类表达式基类_ 是字面量类的 = (cast(字面量类表达式基类_)(n));
    if ((是字面量类的 !is ··null!(字面量类表达式基类_)) && 是字面量类的.isUnterminated) {
        return false;
    }
    return true;
}
void 输出限定名(限定名_ n) {
    if (n.左侧 !is ··null!(限定名_)) {
        .emitEntityName(n.左侧);
        writePunctuation("."d);
    }
    emit(n.右侧);
}
void 输出运算符签名元素(运算符签名元素_ n) {
    writeToken(n.运算符, n.开始, cast(void delegate(dstring))(·fd(&writePunctuation)));
    if (n.类型 !is ··null!(节点_)) {
        writeSpace();
        emit(n.类型);
    }
}
void 输出类型形参(类型形参_ n) {
    if (n.名称 !is ··null!(··Klang节点_.Klang标识符_)) {
        emit(n.名称);
    }
    if (n.约束 !is ··null!(节点_)) {
        writePunctuation(":"d);
        writeSpace();
        emit(n.约束);
    }
}
void emitParameter(形参声明_ n) {
    .emitModifiers(n, ·to!(节点数组_!(节点_))(n.修饰符));
    .emitNodeWithWriter(n.名称, cast(void delegate(dstring))(·fd(&writeParameter)));
    if (n.问号 !is ··null!(KSK)) {
        writePunctuation("?"d);
    }
    .emitTypeAnnotation(n.类型);
    // The comment position has to fallback to any present node within the parameterdeclaration because as it turns out, the parser can make parameter declarations with _just_ an initializer.
    .emitInitializer(n.初始化);
}
void 输出属性声明(属性声明_ n) {
    .emitModifiers(n, ·to!(节点数组_!(节点_))(n.修饰符));
    emit(n.名称);
    if (n.问号 == KSK.问号) {
        writePunctuation("?"d);
    }
    .emitTypeAnnotation(n.类型);
    .emitInitializer(n.初始化);
    writeTrailingSemicolon();
}
void 输出方法声明(方法声明_ n) {
    .emitModifiers(n, ·to!(节点数组_!(节点_))(n.修饰符));
    emit(n.名称);
    .emitSignatureAndBody((cast(函数类声明_)(n)), cast(void delegate(签名声明_))(·fd(&.emitSignatureHead)));
}
void 输出释放声明(释放声明_ n) {
    .emitModifiers(n, ·to!(节点数组_!(节点_))(n.修饰符));
    writeKeyword("释放"d);
    .emitSignatureAndBody((cast(函数类声明_)(n)), cast(void delegate(签名声明_))(·fd(&.emitSignatureHead)));
}
void 输出构建声明(构建声明_ n) {
    .emitModifiers(n, ·to!(节点数组_!(节点_))(n.修饰符));
    writeKeyword("构建"d);
    .emitSignatureAndBody((cast(函数类声明_)(n)), cast(void delegate(签名声明_))(·fd(&.emitSignatureHead)));
}
void 输出索引签名(索引签名_ n) {
    .emitModifiers(n, ·to!(节点数组_!(节点_))(n.修饰符));
    writePunctuation("["d);
    if (n.形参 !is ··null!(形参声明_)) {
        .emitParameter(n.形参);
    }
    writePunctuation("]"d);
    .emitTypeAnnotation(n.类型);
    writeTrailingSemicolon();
}
void 输出运算符签名(运算符签名_ n) {
    .emitModifiers(n, ·to!(节点数组_!(节点_))(n.修饰符));
    .输出运算符元素列表(n, ·to!(节点数组_!(节点_))(n.运算符组));
    .emitTypeAnnotation(n.类型);
    writeTrailingSemicolon();
}
void 输出运算符元素列表(运算符签名_ n, 节点数组_!(节点_) ns = ··null!(节点数组_!(节点_))) {
    if ((ns is null) || (ns.原型 is ··null!(节点_[]))) {
        writePunctuation("["d);
        writePunctuation("]"d);
    }
    else {
        emitList(n, ·to!(节点数组_!(基础节点_))(ns), ListFormat.运算符元素组_);
    }
}
void 输出类型引用(类型引用_ n) {
    emit(n.类型名称);
    .emitTypeArguments(n, n.类型实参组);
}
void 输出函数类型(函数类型_ n) {
    if ((n.父节点 !is ··null!(基础节点_)) && n.父节点.目标种类 != KSK.括号类型) {
        writePunctuation("("d);
    }
    .emitTypeParameters(n, ·to!(节点数组_!(节点_))(n.类型形参));
    .emitParameters(n, ·to!(节点数组_!(节点_))(n.形参组));
    writeSpace();
    writePunctuation("=>"d);
    writeSpace();
    emit(n.类型);
    if ((n.父节点 !is ··null!(基础节点_)) && n.父节点.目标种类 != KSK.括号类型) {
        writePunctuation(")"d);
    }
}
void 输出字面量类型(字面量类型_ n) {
    .输出表达式(n.字面量);
}
void 输出指针类型(指针类型_ n) {
    emit(n.类型);
    writePunctuation("*"d);
}
void 输出数组类型(数组类型_ n) {
    emit(n.类型);
    writePunctuation("["d);
    emit(n.长度);
    writePunctuation("]"d);
}
void 输出动态数组类型(动态数组类型_ n) {
    emit(n.类型);
    writePunctuation("["d);
    writePunctuation("]"d);
}
void 输出括号类型(括号类型_ n) {
    writePunctuation("("d);
    emit(n.类型);
    writePunctuation(")"d);
}
void 输出词典类型(词典类型_ n) {
    emit(n.值类型);
    writePunctuation("."d);
    writePunctuation("["d);
    emit(n.键类型);
    writePunctuation("]"d);
}
void 输出元组类型节点(元组类型节点_ n) {
    emitList(n, ·to!(节点数组_!(基础节点_))(n.类型组), ListFormat.运算符元素组_);
}
void 输出区间类型节点(区间类型节点_ n) {
    emit(n.区间开始);
    writePunctuation("~"d);
    emit(n.区间结束);
}
void 输出类型列表(类型列表_ n) {
    emitList(n, ·to!(节点数组_!(基础节点_))(n.类型组), ListFormat.类型列表类型组_);
}
void 输出联合类型(联合类型_ n) {
    emitList(n, ·to!(节点数组_!(基础节点_))(n.类型组), ListFormat.UnionTypeConstituents);
}
void 输出变长参数(变长参数_ n) {
    writePunctuation("..."d);
    emit(n.类型);
}
void 输出类型限定类型(类型限定类型_ n) {
    writeToken(n.限定符, n.开始, cast(void delegate(dstring))(·fd(&writeKeyword)));
    writeSpace();
    emit(n.类型);
}
void 输出表达式包含类型实参(表达式包含类型实参_ n) {
    .输出表达式(n.表达式);
    .emitTypeArguments(n, n.类型实参组);
}
void 输出导入成员(导入成员_ n) {
    if (n.是公开的) {
        writeKeyword("公开"d);
        writeSpace();
    }
    if (n.另命名名称 !is ··null!(··Klang节点_.Klang标识符_)) {
        emit(n.另命名名称);
        writePunctuation(":"d);
        writeSpace();
    }
    writePunctuation("\""d);
    writeLiteral(n.模块名.内容);
    writePunctuation("\""d);
}
void 输出导入声明(导入声明_ n) {
    writeKeyword("导入"d);
    emitList(n, ·to!(节点数组_!(基础节点_))(n.导入组), ListFormat.导入声明_);
}
void 输出导入从成员(导入从成员_ n) {
    if (n.另命名名称 !is ··null!(··Klang节点_.Klang标识符_)) {
        emit(n.另命名名称);
        writePunctuation(":"d);
        writeSpace();
    }
    emit(n.名称);
}
void 输出导入版本成员(导入版本成员_ n) {
    long openParenPos = emitTokenWithComment(KSK.版本_, n.开始, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
    writeSpace();
    emitTokenWithComment(KSK.左括号, openParenPos, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    .输出表达式(n.表达式);
    emitTokenWithComment(KSK.右括号, n.表达式.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    writeSpace();
    emit(n.然后语句);
    if (n.否则语句 !is ··null!(··Klang节点_.导入成员基类_)) {
        writeLineOrSpace(n, n.然后语句, n.否则语句);
        emitTokenWithComment(KSK.否则_, n.然后语句.结束, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
        writeSpace();
        emit(n.否则语句);
    }
}
void 输出导入成员块(导入成员块_ n) {
    if ((getEmitFlags(n) & EmitFlags.不缩进合成块_) != 0) {
        foreach (··Klang节点_.导入成员基类_ y; n.语句组) {
            emit(y);
            writeLine();
        }
    }
    else {
        emitList(n, ·to!(节点数组_!(基础节点_))(n.语句组), ListFormat.导入声明_);
    }
}
void 输出导入从版本成员(导入从版本成员_ n) {
    long openParenPos = emitTokenWithComment(KSK.版本_, n.开始, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
    writeSpace();
    emitTokenWithComment(KSK.左括号, openParenPos, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    .输出表达式(n.表达式);
    emitTokenWithComment(KSK.右括号, n.表达式.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    writeSpace();
    emit(n.然后语句);
    if (n.否则语句 !is ··null!(··Klang节点_.导入从成员基类_)) {
        writeLineOrSpace(n, n.然后语句, n.否则语句);
        emitTokenWithComment(KSK.否则_, n.然后语句.结束, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
        writeSpace();
        emit(n.否则语句);
    }
}
void 输出导入从成员块(导入从成员块_ n) {
    if ((getEmitFlags(n) & EmitFlags.不缩进合成块_) != 0) {
        foreach (··Klang节点_.导入从成员基类_ y; n.语句组) {
            emit(y);
            writeLine();
        }
    }
    else {
        emitList(n, ·to!(节点数组_!(基础节点_))(n.语句组), ListFormat.导入声明_);
    }
}
void 输出导入从声明(导入从声明_ n) {
    writeKeyword("导入"d);
    writeSpace();
    writePunctuation("\""d);
    writeLiteral(n.模块名.内容);
    writePunctuation("\""d);
    writeSpace();
    emitList(n, ·to!(节点数组_!(基础节点_))(n.导入组), ListFormat.导入声明_);
}
void 输出版本表达式语句(版本表达式语句_ n) {
    writeKeyword("版本"d);
    writeSpace();
    writePunctuation("="d);
    writeSpace();
    emit(n.表达式);
    writeTrailingSemicolon();
}
void 输出程序声明(程序声明_ n) {
    writeKeyword("程序"d);
    writeSpace();
    emit(n.名称);
    writeSpace();
    emitTokenWithComment(KSK.左大括号, n.开始, cast(void delegate(dstring))(·fd(&writePunctuation)), /*contextNode*/ n);
    ListFormat format = (getEmitFlags(n) & EmitFlags.SingleLine) != 0 ? ListFormat.SingleLineBlockStatements : ListFormat.MultiLineBlockStatements;
    emitList(n, ·to!(节点数组_!(基础节点_))(n.语句组), format);
    long 结束 = n.语句组 ? n.语句组.结束 : n.结束;
    emitTokenWithComment(KSK.右大括号, 结束, cast(void delegate(dstring))(·fd(&writePunctuation)), /*contextNode*/ n, (format & ListFormat.MultiLine) != 0);
}
void 输出测试单元语句(测试单元语句_ n) {
    writeKeyword("测试"d);
    writeSpace();
    emitTokenWithComment(KSK.左大括号, n.开始, cast(void delegate(dstring))(·fd(&writePunctuation)), /*contextNode*/ n);
    ListFormat format = (getEmitFlags(n) & EmitFlags.SingleLine) != 0 ? ListFormat.SingleLineBlockStatements : ListFormat.MultiLineBlockStatements;
    emitList(n, ·to!(节点数组_!(基础节点_))(n.语句组), format);
    long 结束 = n.语句组 ? n.语句组.结束 : n.结束;
    emitTokenWithComment(KSK.右大括号, 结束, cast(void delegate(dstring))(·fd(&writePunctuation)), /*contextNode*/ n, (format & ListFormat.MultiLine) != 0);
}
void 输出块(块_ n) {
    if ((getEmitFlags(n) & EmitFlags.不缩进合成块_) != 0) {
        if ((n.语句组 !is null) && (n.语句组.原型 !is ··null!(节点_[]))) {
            foreach (节点_ y; n.语句组) {
                emit(y);
                writeLine();
            }
        }
    }
    else {
        .emitModifiers(n, ·to!(节点数组_!(节点_))(n.修饰符));
        emitTokenWithComment(KSK.左大括号, n.开始, cast(void delegate(dstring))(·fd(&writePunctuation)), /*contextNode*/ n);
        ListFormat format = (getEmitFlags(n) & EmitFlags.SingleLine) != 0 ? ListFormat.SingleLineBlockStatements : ListFormat.MultiLineBlockStatements;
        emitList(n, ·to!(节点数组_!(基础节点_))(n.语句组), format);
        long 结束 = n.语句组 ? n.语句组.结束 : n.结束;
        emitTokenWithComment(KSK.右大括号, 结束, cast(void delegate(dstring))(·fd(&writePunctuation)), /*contextNode*/ n, (format & ListFormat.MultiLine) != 0);
    }
}
void 输出指令语句(指令语句_ n) {
    writeKeyword("指令"d);
    bool 有括号 = (n.名称 !is ··null!(··Klang节点_.Klang标识符_)) || (n.参数 !is ··null!(··节点_.文本字面量_));
    if (有括号) {
        writePunctuation("("d);
    }
    if (n.名称 !is ··null!(··Klang节点_.Klang标识符_)) {
        emit(n.名称);
        if (n.参数 !is ··null!(··节点_.文本字面量_)) {
            writePunctuation(","d);
            writeSpace();
        }
        writePunctuation("\""d);
        writeLiteral(n.参数.内容);
        writePunctuation("\""d);
    }
    if (有括号) {
        writePunctuation(")"d);
    }
    writeTrailingSemicolon();
}
void 输出空语句(空语句_ n) {
    writeTrailingSemicolon();
}
void 输出变量语句(变量语句_ n) {
    .emitModifiers(n, ·to!(节点数组_!(节点_))(n.修饰符));
    emit(n.声明列表);
    writeTrailingSemicolon();
}
void 输出变量声明列表(变量声明列表_ n) {
    bool isVarConst = (获取节点标志(n) & 节点标志_.Const) != 0;
    writeKeyword(isVarConst ? "常量"d : "变量"d);
    writeSpace();
    emitList(n, ·to!(节点数组_!(基础节点_))(n.声明组), ListFormat.VariableDeclarationList);
}
void 输出变量声明(变量声明_ n) {
    .emitModifiers(n, ·to!(节点数组_!(节点_))(n.修饰符));
    emit(n.名称);
    emit(n.叹号令牌);
    .emitTypeAnnotation(n.类型);
    .emitInitializer(n.初始化);
}
void 输出表达式语句(表达式语句_ n) {
    .输出表达式(n.表达式);
    writeTrailingSemicolon();
}
void 输出版本语句(版本语句_ n) {
    long openParenPos = emitTokenWithComment(KSK.版本_, n.开始, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
    writeSpace();
    emitTokenWithComment(KSK.左括号, openParenPos, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    .输出表达式(n.表达式);
    emitTokenWithComment(KSK.右括号, n.表达式.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    writeSpace();
    emit(n.然后语句);
    if (n.否则语句 !is ··null!(节点_)) {
        writeLineOrSpace(n, n.然后语句, n.否则语句);
        emitTokenWithComment(KSK.否则_, n.然后语句.结束, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
        writeSpace();
        emit(n.否则语句);
    }
}
void 输出如果语句(如果语句_ n, KSK keyword = KSK.如果_) {
    long openParenPos = emitTokenWithComment(keyword, n.开始, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
    writeSpace();
    emitTokenWithComment(KSK.左括号, openParenPos, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    .输出表达式(n.表达式);
    emitTokenWithComment(KSK.右括号, n.表达式.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    writeSpace();
    emit(n.然后语句);
    if (n.否则语句 !is ··null!(节点_)) {
        if (n.否则语句.目标种类 == KSK.如果语句) {
            writeLineOrSpace(n, n.然后语句, n.否则语句);
            .输出如果语句((cast(如果语句_)(n.否则语句)), KSK.另如_);
        }
        else {
            writeLineOrSpace(n, n.然后语句, n.否则语句);
            emitTokenWithComment(KSK.否则_, n.然后语句.结束, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
            writeSpace();
            emit(n.否则语句);
        }
    }
}
void 输出循环语句(循环语句_ n) {
    long openParenPos = emitTokenWithComment(KSK.循环_, n.开始, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
    writeSpace();
    long pos = emitTokenWithComment(KSK.左括号, openParenPos, cast(void delegate(dstring))(·fd(&writePunctuation)), /*contextNode*/ n);
    emit(n.初始化);
    pos = emitTokenWithComment(KSK.分号, n.初始化 ? n.初始化.结束 : pos, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    if (n.条件 !is ··null!(节点_)) {
        writeSpace();
    }
    emit(n.条件);
    pos = emitTokenWithComment(KSK.分号, n.条件 ? n.条件.结束 : pos, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    if (n.自增 !is ··null!(节点_)) {
        writeSpace();
    }
    emit(n.自增);
    emitTokenWithComment(KSK.右括号, n.自增 ? n.自增.结束 : pos, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    emit(n.语句);
}
void 输出循环属于(循环属于_ n) {
    long openParenPos = emitTokenWithComment(KSK.循环_, n.开始, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
    writeSpace();
    long pos = emitTokenWithComment(KSK.左括号, openParenPos, cast(void delegate(dstring))(·fd(&writePunctuation)), /*contextNode*/ n);
    emit(n.初始化);
    writeSpace();
    writeKeyword("属于"d);
    writeSpace();
    emit(n.表达式);
    emitTokenWithComment(KSK.右括号, n.表达式.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), /*contextNode*/ n);
    writeSpace();
    emit(n.语句);
}
void 输出当循环语句(当循环语句_ n) {
    long openParenPos = emitTokenWithComment(KSK.循环_, n.开始, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
    writeSpace();
    long pos = emitTokenWithComment(KSK.左括号, openParenPos, cast(void delegate(dstring))(·fd(&writePunctuation)), /*contextNode*/ n);
    emit(n.表达式);
    emitTokenWithComment(KSK.右括号, n.表达式.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), /*contextNode*/ n);
    writeSpace();
    emit(n.语句);
}
void 输出继续语句(继续语句_ n) {
    emitTokenWithComment(KSK.继续_, n.开始, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
    if (n.标签 !is ··null!(··Klang节点_.Klang标识符_)) {
        writeSpace();
    }
    emit(n.标签);
    writeTrailingSemicolon();
}
void 输出跳出语句(跳出语句_ n) {
    emitTokenWithComment(KSK.跳出_, n.开始, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
    if (n.标签 !is ··null!(··Klang节点_.Klang标识符_)) {
        writeSpace();
    }
    emit(n.标签);
    writeTrailingSemicolon();
}
void 输出抛出语句(抛出语句_ n) {
    writeKeyword("抛出"d);
    writeSpace();
    emit(n.表达式);
    writeTrailingSemicolon();
}
void 输出断言语句(断言语句_ n) {
    writeKeyword("断言"d);
    .输出表达式列表(n, n.实参组, ListFormat.CallExpressionArguments);
    writeTrailingSemicolon();
}
void 输出同步语句(同步语句_ n) {
    writeKeyword("同步"d);
    .输出表达式列表(n, n.实参组, ListFormat.CallExpressionArguments);
    emitTokenWithComment(KSK.左大括号, n.开始, cast(void delegate(dstring))(·fd(&writePunctuation)), /*contextNode*/ n);
    ListFormat format = (getEmitFlags(n) & EmitFlags.SingleLine) != 0 ? ListFormat.SingleLineBlockStatements : ListFormat.MultiLineBlockStatements;
    emitList(n, ·to!(节点数组_!(基础节点_))(n.语句组), format);
    long 结束 = n.语句组 ? n.语句组.结束 : n.结束;
    emitTokenWithComment(KSK.右大括号, 结束, cast(void delegate(dstring))(·fd(&writePunctuation)), /*contextNode*/ n, (format & ListFormat.MultiLine) != 0);
}
void 输出调试语句(调试语句_ n) {
    writeKeyword("调试"d);
    writeTrailingSemicolon();
}
void 输出标签语句(标签语句_ n) {
    emit(n.标签);
    emitTokenWithComment(KSK.冒号, n.标签.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    writeSpace();
    emit(n.语句);
}
void 输出延迟语句(延迟语句_ n) {
    writeKeyword("延迟"d);
    writeSpace();
    emit(n.语句);
}
void 输出删除语句(删除语句_ n) {
    writeKeyword("删除"d);
    writeSpace();
    emit(n.表达式);
    writeTrailingSemicolon();
}
void 输出返回语句(返回语句_ n) {
    writeKeyword("返回"d);
    if (n.表达式 !is ··null!(节点_)) {
        writeSpace();
        emit(n.表达式);
        writeTrailingSemicolon();
    }
}
void 输出假如语句(假如语句_ n) {
    long openParenPos = emitTokenWithComment(KSK.假如_, n.开始, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
    writeSpace();
    emitTokenWithComment(KSK.左括号, openParenPos, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    .输出表达式(n.表达式);
    emitTokenWithComment(KSK.右括号, n.表达式.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    writeSpace();
    emit(n.若是块);
}
void 输出若是块(若是块_ n) {
    emitTokenWithComment(KSK.左大括号, n.开始, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    emitList(n, ·to!(节点数组_!(基础节点_))(n.子句组), ListFormat.CaseBlockClauses);
    emitTokenWithComment(KSK.右大括号, n.子句组.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), n, /*indentLeading*/ true);
}
void 输出若是子句(若是子句_ n) {
    emitTokenWithComment(KSK.若是_, n.开始, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
    writeSpace();
    emit(n.表达式);
    .emitCaseOrDefaultClauseRest(n, n.语句组, n.表达式.结束);
}
void 输出默认子句(默认子句_ n) {
    long pos = emitTokenWithComment(KSK.默认_, n.开始, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
    .emitCaseOrDefaultClauseRest(n, n.语句组, pos);
}
void emitCaseOrDefaultClauseRest(节点_ parentNode, 节点数组_!(节点_) statements, long colonPos) {
    bool emitAsSingleStatement = statements.length == 1 && 
    // treat synthesized nodes as located on the same line for emit purposes
    (nodeIsSynthesized(parentNode) || nodeIsSynthesized(statements[0]) || (基础环境.currentSourceFile !is ··null!(基础源文件_)) && ((基础环境.currentSourceFile.内容) !is ··null!(dstring)) && rangeStartPositionsAreOnSameLine(parentNode, statements[0], 基础环境.currentSourceFile));
    ListFormat format = ListFormat.CaseOrDefaultClauseStatements;
    if (emitAsSingleStatement) {
        writeToken(KSK.冒号, colonPos, cast(void delegate(dstring))(·fd(&writePunctuation)), parentNode);
        writeSpace();
        format &= ~(ListFormat.MultiLine | ListFormat.Indented);
    }
    else {
        emitTokenWithComment(KSK.冒号, colonPos, cast(void delegate(dstring))(·fd(&writePunctuation)), parentNode);
    }
    emitList(parentNode, ·to!(节点数组_!(基础节点_))(statements), format);
}
void 输出继承子句(继承子句_ n) {
    writeSpace();
    writeTokenText(KSK.冒号, cast(void delegate(dstring))(·fd(&writeKeyword)), n.开始);
    writeSpace();
    emitList(n, ·to!(节点数组_!(基础节点_))(n.类型组), ListFormat.HeritageClauseTypes);
}
void 输出尝试语句(尝试语句_ n) {
    emitTokenWithComment(KSK.尝试_, n.开始, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
    writeSpace();
    emit(n.尝试块);
    if (n.捕获子句 !is ··null!(捕获子句_)) {
        writeLineOrSpace(n, n.尝试块, n.捕获子句);
        emit(n.捕获子句);
    }
    if (n.最后块 !is ··null!(块_)) {
        节点_ 预处理子 = n.捕获子句;
        if (预处理子 is ··null!(节点_)) {
            预处理子 = n.尝试块;
        }
        writeLineOrSpace(n, 预处理子, n.最后块);
        emitTokenWithComment(KSK.最后_, 预处理子.结束, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
        writeSpace();
        emit(n.最后块);
    }
}
void 输出捕获子句(捕获子句_ n) {
    long openParenPos = emitTokenWithComment(KSK.捕获_, n.开始, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
    writeSpace();
    if (n.变量声明 !is ··null!(节点_)) {
        emitTokenWithComment(KSK.左括号, openParenPos, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
        emit(n.变量声明);
        emitTokenWithComment(KSK.右括号, n.变量声明.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
        writeSpace();
    }
    emit(n.块);
}
void 输出属性赋值(属性赋值_ n) {
    emit(n.名称);
    writePunctuation(":"d);
    writeSpace();
    // This is to ensure that we emit comment in the following case:
    //      For example:
    //          obj = {
    //              id: /*comment1*/ ()=>void
    //          }
    // "comment1" is not considered to be leading comment for node.initializer
    // but rather a trailing comment on the previous node.
    节点_ initializer = n.初始化;
    if ((getEmitFlags(initializer) & EmitFlags.NoLeadingComments) == 0) {
        ··类型_.文本范围_ commentRange = getCommentRange(initializer);
        emitTrailingCommentsOfPosition(commentRange.开始);
    }
    .输出表达式(initializer);
}
void 输出简洁属性赋值(简洁属性赋值_ n) {
    emit(n.名称);
    if (n.初始化 !is ··null!(节点_)) {
        writeSpace();
        writePunctuation("="d);
        writeSpace();
        .输出表达式(n.初始化);
    }
}
void 输出函数声明(函数声明_ n) {
    .emitModifiers(n, ·to!(节点数组_!(节点_))(n.修饰符));
    if ((n.标志 & (节点标志_.是启动函数 | 节点标志_.是测试启动函数)) == 0) {
        writeKeyword("函数"d);
        writeSpace();
    }
    emit(n.名称);
    .emitSignatureAndBody(n, cast(void delegate(签名声明_))(·fd(&.emitSignatureHead)));
}
void 输出对象声明(对象声明_ n) {
    .emitModifiers(n, ·to!(节点数组_!(节点_))(n.修饰符));
    writeKeyword("对象"d);
    writeSpace();
    emit(n.名称);
    EmitFlags indentedFlag = getEmitFlags(n) & EmitFlags.Indented;
    if (indentedFlag != EmitFlags.None) {
        increaseIndent();
    }
    .emitTypeParameters(n, ·to!(节点数组_!(节点_))(n.类型形参));
    emitList(n, ·to!(节点数组_!(基础节点_))(n.继承子句), ListFormat.ClassHeritageClauses);
    writeSpace();
    writePunctuation("{"d);
    emitList(n, ·to!(节点数组_!(基础节点_))(n.成员组), ListFormat.ClassMembers);
    writePunctuation("}"d);
    if (indentedFlag != EmitFlags.None) {
        decreaseIndent();
    }
}
void 输出结构声明(结构声明_ n) {
    .emitModifiers(n, ·to!(节点数组_!(节点_))(n.修饰符));
    writeKeyword("结构"d);
    writeSpace();
    emit(n.名称);
    EmitFlags indentedFlag = getEmitFlags(n) & EmitFlags.Indented;
    if (indentedFlag != EmitFlags.None) {
        increaseIndent();
    }
    .emitTypeParameters(n, ·to!(节点数组_!(节点_))(n.类型形参));
    emitList(n, ·to!(节点数组_!(基础节点_))(n.继承子句), ListFormat.ClassHeritageClauses);
    writeSpace();
    writePunctuation("{"d);
    emitList(n, ·to!(节点数组_!(基础节点_))(n.成员组), ListFormat.ClassMembers);
    writePunctuation("}"d);
    if (indentedFlag != EmitFlags.None) {
        decreaseIndent();
    }
}
void 输出枚举声明(枚举声明_ n) {
    .emitModifiers(n, ·to!(节点数组_!(节点_))(n.修饰符));
    writeKeyword("枚举"d);
    writeSpace();
    emit(n.名称);
    if (n.类型 !is ··null!(节点_)) {
        writePunctuation(":"d);
        writeSpace();
        emit(n.类型);
    }
    EmitFlags indentedFlag = getEmitFlags(n) & EmitFlags.Indented;
    if (indentedFlag != EmitFlags.None) {
        increaseIndent();
    }
    writeSpace();
    writePunctuation("{"d);
    emitList(n, ·to!(节点数组_!(基础节点_))(n.成员组), ListFormat.ClassMembers);
    writePunctuation("}"d);
    if (indentedFlag != EmitFlags.None) {
        decreaseIndent();
    }
}
void 输出接口声明(接口声明_ n) {
    .emitModifiers(n, ·to!(节点数组_!(节点_))(n.修饰符));
    writeKeyword("接口"d);
    writeSpace();
    emit(n.名称);
    EmitFlags indentedFlag = getEmitFlags(n) & EmitFlags.Indented;
    if (indentedFlag != EmitFlags.None) {
        increaseIndent();
    }
    .emitTypeParameters(n, ·to!(节点数组_!(节点_))(n.类型形参));
    emitList(n, ·to!(节点数组_!(基础节点_))(n.继承子句), ListFormat.ClassHeritageClauses);
    writeSpace();
    writePunctuation("{"d);
    emitList(n, ·to!(节点数组_!(基础节点_))(n.成员组), ListFormat.ClassMembers);
    writePunctuation("}"d);
    if (indentedFlag != EmitFlags.None) {
        decreaseIndent();
    }
}
void 输出类型声明(类型声明_ n) {
    .emitModifiers(n, ·to!(节点数组_!(节点_))(n.修饰符));
    writeKeyword("类型"d);
    writeSpace();
    emit(n.名称);
    .emitTypeParameters(n, ·to!(节点数组_!(节点_))(n.类型形参));
    if (n.类型 !is ··null!(节点_)) {
        writePunctuation(":"d);
        writeSpace();
        emit(n.类型);
    }
    EmitFlags indentedFlag = getEmitFlags(n) & EmitFlags.Indented;
    if (indentedFlag != EmitFlags.None) {
        increaseIndent();
    }
    writeSpace();
    writePunctuation("{"d);
    emitList(n, ·to!(节点数组_!(基础节点_))(n.成员组), ListFormat.ClassMembers);
    writePunctuation("}"d);
    if (indentedFlag != EmitFlags.None) {
        decreaseIndent();
    }
}
void 输出别名声明(别名声明_ n) {
    .emitModifiers(n, ·to!(节点数组_!(节点_))(n.修饰符));
    writeKeyword("别名"d);
    writeSpace();
    emit(n.名称);
    .emitTypeParameters(n, ·to!(节点数组_!(节点_))(n.类型形参));
    writeSpace();
    writePunctuation("="d);
    writeSpace();
    emit(n.类型);
    writeTrailingSemicolon();
}
void 输出枚举成员(枚举成员_ n) {
    emit(n.名称);
    .emitInitializer(n.初始化);
    writeTrailingSemicolon();
}
void 输出外部修饰符声明(外部修饰符声明_ n) {
    emitTokenWithComment(KSK.外部_, n.开始, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
    writePunctuation("("d);
    emit(n.修饰符节点);
    if (n.名称空间 !is ··null!(限定名_)) {
        writePunctuation(","d);
        writeSpace();
        emit(n.名称空间);
    }
    writePunctuation(")"d);
}
void 输出标识符修饰符(标识符修饰符_ n) {
    emit(n.标识符);
}
void emitSignatureHead(签名声明_ n) {
    .emitTypeParameters(n, ·to!(节点数组_!(节点_))(n.类型形参));
    .emitParameters(n, ·to!(节点数组_!(节点_))(n.形参组));
    .emitTypeAnnotation(n.类型);
}
void emitSignatureAndBody(函数类声明_ n, void delegate(签名声明_) emitSignatureHead) {
    基础节点_ 函数体 = n.函数体;
    if (函数体 !is ··null!(基础节点_)) {
        if (函数体.目标种类 == KSK.块) {
            EmitFlags indentedFlag = getEmitFlags(n) & EmitFlags.Indented;
            if (indentedFlag != EmitFlags.None) {
                increaseIndent();
            }
            emitSignatureHead(n);
            .emitBlockFunctionBody((cast(块_)(函数体)));
            if (indentedFlag != EmitFlags.None) {
                decreaseIndent();
            }
        }
        else {
            emitSignatureHead(n);
            writeSpace();
            .输出表达式((cast(节点_)(函数体)));
        }
    }
    else {
        emitSignatureHead(n);
        writeTrailingSemicolon();
    }
}
void emitBlockFunctionBody(块_ 函数体) {
    if (onBeforeEmitNode !is ··null!(void delegate(基础节点_))) {
        onBeforeEmitNode(函数体);
    }
    writeSpace();
    writePunctuation("{"d);
    increaseIndent();
    bool 输出单行 = .shouldEmitBlockFunctionBodyOnSingleLine(函数体);
    ··类型_.文本范围_ 范围 = createRange(-1, -1);
    if ((函数体.语句组 !is null) && (函数体.语句组.原型 !is ··null!(节点_[]))) {
        范围.开始 = 函数体.语句组.开始;
        范围.结束 = 函数体.语句组.结束;
    }
    if (输出单行) {
        emitBodyWithDetachedComments(函数体, 范围, (基础节点_ s) { return .输出块函数体在单行((cast(块_)(s))); });
    }
    else {
        emitBodyWithDetachedComments(函数体, 范围, (基础节点_ s) { return .输出块函数体在多行((cast(块_)(s))); });
    }
    decreaseIndent();
    writeToken(KSK.右大括号, 函数体.语句组.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), 函数体);
    if (onAfterEmitNode !is ··null!(void delegate(基础节点_))) {
        onAfterEmitNode(函数体);
    }
}
bool shouldEmitBlockFunctionBodyOnSingleLine(块_ 函数体) {
    // We must emit a 函数 body as a single-line body in the following case:
    // * The body has NodeEmitFlags.SingleLine specified.
    // We must emit a 函数 body as a multi-line body in the following cases:
    // * The body is explicitly marked as multi-line.
    // * A non-synthesized body's start and 结束 position are on different lines.
    // * Any statement in the body starts on a new line.
    if ((getEmitFlags(函数体) & EmitFlags.SingleLine) != 0) {
        return true;
    }
    if (函数体.多行) {
        return false;
    }
    if (!nodeIsSynthesized(函数体) && (基础环境.currentSourceFile !is ··null!(基础源文件_)) && ((基础环境.currentSourceFile.内容) !is ··null!(dstring)) && !rangeIsOnSingleLine(函数体, 基础环境.currentSourceFile)) {
        return false;
    }
    if (getLeadingLineTerminatorCount(函数体, (cast(基础节点_[])(函数体.语句组.原型)), ListFormat.PreserveLines) != 0 || getClosingLineTerminatorCount(函数体, ·to!(节点数组_!(基础节点_))(函数体.语句组), ListFormat.PreserveLines) != 0) {
        return false;
    }
    节点_ previousStatement;
    foreach (节点_ statement; 函数体.语句组) {
        if (getSeparatingLineTerminatorCount(previousStatement, statement, ListFormat.PreserveLines) > 0) {
            return false;
        }
        previousStatement = statement;
    }
    return true;
}
void 输出块函数体在单行(块_ 函数体) {
    .emitBlockFunctionBodyWorker(函数体, /*输出块函数体在单行*/ true);
}
void 输出块函数体在多行(块_ 函数体) {
    .emitBlockFunctionBodyWorker(函数体, /*输出块函数体在单行*/ false);
}
void emitBlockFunctionBodyWorker(块_ 函数体, bool 输出块函数体在单行 = ··null!(bool)) {
    long pos = 基础环境.writer.getTextPos();
    if (pos == 基础环境.writer.getTextPos() && 输出块函数体在单行) {
        decreaseIndent();
        emitList(函数体, ·to!(节点数组_!(基础节点_))(函数体.语句组), ListFormat.SingleLineFunctionBodyStatements);
        increaseIndent();
    }
    else {
        emitList(函数体, ·to!(节点数组_!(基础节点_))(函数体.语句组), ListFormat.MultiLineFunctionBodyStatements);
    }
}
void 输出数组字面量表达式(数组字面量表达式_ n) {
    节点数组_!(节点_) elements = n.元素组;
    ListFormat preferNewLine = n.多行 ? ListFormat.PreferNewLine : ListFormat.None;
    .输出表达式列表(n, elements, ListFormat.ArrayLiteralExpressionElements | preferNewLine);
}
void 输出动态类字面量表达式(动态类字面量表达式_ n) {
    节点数组_!(节点_) elements = n.元素组;
    ListFormat preferNewLine = n.多行 ? ListFormat.PreferNewLine : ListFormat.None;
    .输出表达式列表(n, elements, ListFormat.动态类字面量表达式_ | preferNewLine);
}
void 输出词典键值表达式(词典键值表达式_ n) {
    .输出表达式(n.键表达式);
    writePunctuation(":"d);
    writeSpace();
    .输出表达式(n.值表达式);
}
void 输出结构字面量表达式(结构字面量表达式_ n) {
    emit(n.类型注释节点);
    ListFormat preferNewLine = n.多行 ? ListFormat.PreferNewLine : ListFormat.None;
    节点数组_!(节点_) elements = n.属性组;
    .输出表达式列表(n, elements, ListFormat.结构类字面量表达式_ | preferNewLine);
}
void 输出接口字面量表达式(接口字面量表达式_ n) {
    emit(n.类型);
    ListFormat preferNewLine = n.多行 ? ListFormat.PreferNewLine : ListFormat.None;
    节点数组_!(节点_) elements = n.属性组;
    .输出表达式列表(n, elements, ListFormat.结构类字面量表达式_ | preferNewLine);
}
void 输出属性访问表达式(属性访问表达式_ n) {
    .输出表达式(n.左侧);
    emitTokenWithComment(KSK.点号, n.左侧.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    .输出表达式(n.名称);
}
void 输出元素访问表达式(元素访问表达式_ n) {
    .输出表达式(n.表达式);
    emitTokenWithComment(KSK.左方括号, n.表达式.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    .输出表达式(n.参数表达式);
    emitTokenWithComment(KSK.右方括号, n.参数表达式.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
}
void 输出截取表达式(截取表达式_ n) {
    .输出表达式(n.表达式);
    emitTokenWithComment(KSK.左方括号, n.表达式.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    .输出表达式(n.截取开始);
    writePunctuation(".."d);
    .输出表达式(n.截取结尾);
    long 结尾 = n.截取结尾 ? n.截取结尾.结束 : n.截取开始 ? n.截取开始.结束 + 2 : n.表达式.结束 + 3;
    emitTokenWithComment(KSK.左方括号, 结尾, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
}
void 输出调用表达式(调用表达式_ n) {
    .输出表达式(n.表达式);
    .emitTypeArguments(n, n.类型实参组);
    .输出表达式列表(n, n.实参组, ListFormat.CallExpressionArguments);
}
void 输出新建表达式(新建表达式_ n) {
    emitTokenWithComment(KSK.新建_, n.开始, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
    writeSpace();
    emit(n.类型);
    .输出表达式列表(n, n.实参组, ListFormat.CallExpressionArguments);
}
void 输出函数表达式(函数表达式_ n) {
    writeKeyword("函数"d);
    writeSpace();
    emit(n.名称);
    .emitSignatureAndBody(n, cast(void delegate(签名声明_))(·fd(&.emitSignatureHead)));
}
void 输出箭头函数(箭头函数_ n) {
    .emitModifiers(n, ·to!(节点数组_!(节点_))(n.修饰符));
    .emitSignatureAndBody(n, cast(void delegate(签名声明_))(·fd(&.emitArrowFunctionHead)));
}
void emitArrowFunctionHead(签名声明_ n) {
    .emitTypeParameters(n, ·to!(节点数组_!(节点_))(n.类型形参));
    .emitParameters(n, ·to!(节点数组_!(节点_))(n.形参组));
    .emitTypeAnnotation(n.类型);
    writeSpace();
    emitTokenWithComment(KSK.等右尖号, n.开始, cast(void delegate(dstring))(·fd(&writeKeyword)), n);
}
void 输出类型断言表达式(类型断言表达式_ n) {
    emit(n.表达式);
    emitTokenWithComment(KSK.点左尖括号, n.表达式.开始, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    emit(n.类型);
    emitTokenWithComment(KSK.右尖括号, n.类型.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
}
void 输出类型查询表达式(类型查询表达式_ n) {
    emit(n.表达式);
    emitTokenWithComment(KSK.点左尖括号, n.表达式.开始, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    writeKeyword("类型"d);
    emitTokenWithComment(KSK.右尖括号, n.类型.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
}
void 输出类型转换表达式(类型转换表达式_ n) {
    emit(n.表达式);
    emitTokenWithComment(KSK.点左括号, n.类型.开始, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    emit(n.类型);
    emitTokenWithComment(KSK.右括号, n.表达式.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
}
void 输出非空表达式(非空表达式_ n) {
    emit(n.表达式);
    writePunctuation("!"d);
}
void 输出展开表达式(展开表达式_ n) {
    writePunctuation("..."d);
    emit(n.表达式);
}
void 输出条件表达式(条件表达式_ n) {
    long linesBeforeQuestion = getLinesBetweenNodes(n, n.条件, n.当真);
    long linesAfterQuestion = getLinesBetweenNodes(n, n.当真, n.当假);
    emit(n.条件);
    emitTokenWithComment(KSK.问号, n.条件.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    writeLinesAndIndent(linesBeforeQuestion, /*writeSpaceIfNotIndenting*/ true);
    emit(n.当真);
    emitTokenWithComment(KSK.冒号, n.当真.结束, cast(void delegate(dstring))(·fd(&writePunctuation)), n);
    writeLinesAndIndent(linesAfterQuestion, /*writeSpaceIfNotIndenting*/ true);
    emit(n.当假);
}
void 输出模板表达式(模板表达式_ n) {
    emit(n.模板头);
    emitList(n, ·to!(节点数组_!(基础节点_))(n.模板跨度), ListFormat.TemplateExpressionSpans);
    emit(n.模板尾);
}
void 输出前缀一元表达式(前缀一元表达式_ n) {
    writeTokenText(n.运算符, cast(void delegate(dstring))(·fd(&writeOperator)), n.开始);
    if (.shouldEmitWhitespaceBeforeOperand(n)) {
        writeSpace();
    }
    .输出表达式(n.表达式);
}
bool shouldEmitWhitespaceBeforeOperand(前缀一元表达式_ n) {
    节点_ 表达式 = n.表达式;
    return 表达式.目标种类 == KSK.前缀一元表达式 && (n.运算符 == KSK.加号 && ((cast(前缀一元表达式_)(表达式)).运算符 == KSK.加号 || (cast(前缀一元表达式_)(表达式)).运算符 == KSK.加加号) || (n.运算符 == KSK.减号 && ((cast(前缀一元表达式_)(表达式)).运算符 == KSK.减号 || (cast(前缀一元表达式_)(表达式)).运算符 == KSK.减减号)));
}
void 输出后缀一元表达式(后缀一元表达式_ n) {
    .输出表达式(n.表达式);
    writeTokenText(n.运算符, cast(void delegate(dstring))(·fd(&writeOperator)), n.表达式.结束);
}
void 输出二元表达式(二元表达式_ n) {
    bool isCommaOperator = n.运算符 != KSK.逗号;
    long indentBeforeOperator = getLinesBetweenNodes(n, n.左侧, n.右侧);
    .输出表达式(n.左侧);
    writeLinesAndIndent(indentBeforeOperator, /*writeSpaceIfNotIndenting*/ true);
    writeTokenText(n.运算符, cast(void delegate(dstring))(·fd(&writeOperator)), n.左侧.结束);
    writeLinesAndIndent(indentBeforeOperator, /*writeSpaceIfNotIndenting*/ true);
    .输出表达式(n.右侧);
}
void 输出表达式列表表达式(表达式列表表达式_ n) {
    emitList(n, ·to!(节点数组_!(基础节点_))(n.元素组), ListFormat.CommaListElements);
}
void emitNodeWithWriter(节点_ node = ··null!(节点_), void delegate(dstring) writer = ··null!(void delegate(dstring))) {
    if (node is ··null!(节点_)) {
        return;
    }
    void delegate(dstring) savedWrite = getWrite();
    setWrite(cast(void delegate(dstring))(writer));
    emit(node);
    setWrite(cast(void delegate(dstring))(savedWrite));
}
void emitModifiers(节点_ node, 节点数组_!(节点_) modifiers = ··null!(节点数组_!(节点_))) {
    if ((modifiers !is null) && (modifiers.原型 !is ··null!(节点_[])) && (modifiers.length !is ··null!(size_t))) {
        emitList(node, ·to!(节点数组_!(基础节点_))(modifiers), ListFormat.Modifiers);
        writeSpace();
    }
}
void emitTypeAnnotation(节点_ node = ··null!(节点_)) {
    if (node !is ··null!(节点_)) {
        writePunctuation(":"d);
        writeSpace();
        emit(node);
    }
}
void emitInitializer(节点_ node = ··null!(节点_)) {
    if (node !is ··null!(节点_)) {
        writeSpace();
        writePunctuation("="d);
        writeSpace();
        .输出表达式(node);
    }
}
void emitEntityName(节点_ node) {
    if (node.目标种类 == KSK.标识符) {
        .输出表达式(node);
    }
    else {
        emit(node);
    }
}
void emitParameters(节点_ parentNode, 节点数组_!(节点_) parameters) {
    emitList(parentNode, ·to!(节点数组_!(基础节点_))(parameters), ListFormat.Parameters);
}
void emitTypeArguments(节点_ parentNode, 节点数组_!(节点_) typeArguments = ··null!(节点数组_!(节点_))) {
    emitList(parentNode, ·to!(节点数组_!(基础节点_))(typeArguments), ListFormat.TypeArguments);
}
void emitTypeParameters(节点_ parentNode, 节点数组_!(节点_) typeParameters = ··null!(节点数组_!(节点_))) {
    emitList(parentNode, ·to!(节点数组_!(基础节点_))(typeParameters), ListFormat.TypeParameters);
}
void 输出表达式(节点_ node = ··null!(节点_)) {
    if (node is ··null!(节点_)) {
        return;
    }
    pipelineEmit(EmitHint.Expression, node);
}
void 输出表达式列表(节点_ parentNode = ··null!(节点_), 节点数组_!(节点_) children = ··null!(节点数组_!(节点_)), ListFormat format = ··null!(ListFormat), long start = ··null!(long), long count = ··null!(long)) {
    if ((count is ··null!(long)) || count == 0) {
        count = children ? children.length - start : 0;
    }
    emitNodeList(cast(void delegate(基础节点_))(·fd(&emit)), parentNode, ·to!(节点数组_!(基础节点_))(children), format, start, count);
}
